package beans;

import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;

import model.AgentInfo;
import model.AgentType;
import webservice.NodeCommunicationWS;
import agents.Agent;
import agents.MasterAgent;
import agents.MerchantAgent;
import beans.interfaces.AgentDataLocal;
import beans.interfaces.AgentManagerLocal;
import beans.interfaces.TaskManagerLocal;

/**
 * Session Bean implementation class AgentManager
 */
@LocalBean
@Singleton
@Startup
public class AgentManager implements AgentManagerLocal {

	private AgentInfo managerAgentInfo;
	
	@EJB
	private AgentDataLocal agentData;
	
	@EJB
	private NodeCommunicationWS localNode;
	
	@EJB
	private TaskManagerLocal taskManager;
	
	@EJB
	private ConnectionManagerLocal cm;
	
    /**
     * Default constructor. 
     */
    public AgentManager() {
        // TODO Auto-generated constructor stub
    }
    
    @SuppressWarnings("unchecked")
	@PostConstruct
    private void init() {
    	managerAgentInfo=new AgentInfo(cm.getLocalHost(), AgentType.MERCHANT, Integer.MAX_VALUE);
    	
    	
	    EntityManagerFactory factory = Persistence.createEntityManagerFactory("Agent");
	    
	    EntityManager manager = factory.createEntityManager();
	    /*
	    AgentInfo Master = new AgentInfo(cm.getLocalHost(), AgentType.MASTER, 666);
	    AgentInfo Merchant1 = new AgentInfo(cm.getLocalHost(), AgentType.MERCHANT, 1);
	    AgentInfo Merchant2 = new AgentInfo(cm.getLocalHost(), AgentType.MERCHANT, 2);
	    AgentInfo Merchant3 = new AgentInfo(cm.getLocalHost(), AgentType.MERCHANT, 3);
	    */
	    try{
	    	
		      EntityTransaction tx = manager.getTransaction();
		      /*
		      tx.begin();
		      
		      manager.persist(Master);
		      manager.persist(Merchant1);
		      manager.persist(Merchant2);
		      manager.persist(Merchant3);
		      
		      tx.commit();
		      */
		      tx.begin();
		      
		      Query query = manager.createQuery("SELECT a FROM AgentInfo a");
		      List<AgentInfo> list = query.getResultList();
		      
		      int masterCnt = 0, merchantCnt = 0;
		      
		      for(AgentInfo ai : list){
		    	  
		    	  if(ai.getAgentType().equals(AgentType.MASTER)){
		    		  
		    		  agentData.addAgent(new MasterAgent(ai), "master" + masterCnt++);
		    		  
		    	  }else if(ai.getAgentType().equals(AgentType.MERCHANT)){
		    		  
		    		  agentData.addAgent(new MerchantAgent(ai), "merchant" + merchantCnt++);
		    		  
		    	  }else System.out.println("Unknown agent type");
		    	  
		    	  System.out.println("Agent: "+ ai.getAID());
		      }
		      
		      tx.commit();
	    	
	    }catch(Exception e){
	    	
	    	e.printStackTrace();
	    	
	    }finally{
	    	
	    	manager.close();
	    	factory.close();
	    	
	    }
    	
    	//agentData.addAgent(new MasterAgent(new AgentInfo(cm.getLocalHost(), AgentType.MASTER,666)), "master1");
		//agentData.addAgent(new MerchantAgent(new AgentInfo(cm.getLocalHost(), AgentType.MERCHANT,1)), "merchant1");
		//agentData.addAgent(new MerchantAgent(new AgentInfo(cm.getLocalHost(), AgentType.MERCHANT,2)), "merchant2");
		//agentData.addAgent(new MerchantAgent(new AgentInfo(cm.getLocalHost(), AgentType.MERCHANT,3)), "merchant3");
	    
	    //agentData.addAgent(new MasterAgent(Master), "master1");
	    //agentData.addAgent(new MerchantAgent(Merchant1), "merchant1");
	    //agentData.addAgent(new MerchantAgent(Merchant2), "merchant2");
	    //agentData.addAgent(new MerchantAgent(Merchant3), "merchant3");
    }

    @Override
	public AgentInfo getManagerAgentInfo() {
		return managerAgentInfo;
	}

	@Override
	public Agent findAgent(String key) {
		// TODO Auto-generated method stub
		Agent a = agentData.getAgent(key);
		return a;
	}
	
	@Override 
	public AgentInfo findAgentInfo(String key) {
		Agent a = agentData.getAgent(key);
		if(a==null) {
			return null;
		}
		return a.getAgentInfo();
	}
	
	@Override
	public AgentInfo findAnyMasterAgentInfo() {
		for(Agent a : agentData.getAllAgents()) {
			if(a.getAgentInfo().getAgentType().equals(AgentType.MASTER)) {
				return a.getAgentInfo();
			}
		}
		return null;
	}
	
	@Override
	public AgentInfo findAnyNonLocalMasterAgentInfo() {
		return cm.findAnyMasterAgentInfoOnOtherNode();
	}
	
	@Override
	public AgentInfo findAnyTenderStarter() {
		AgentInfo ai = findAnyMasterAgentInfo();
		if(ai==null) {
			ai=findAnyNonLocalMasterAgentInfo();
		}
		return ai;
	}

	@Override
	public void addAgent(String key, Agent agent) {
		// TODO Auto-generated method stub
		agentData.addAgent(agent, key);
	}

	@Override
	public Agent removeAgent(Agent agent) {
		// TODO Auto-generated method stub
		return agentData.removeAgent(agent);
	}

	@Override
	public Agent removeAgent(String key) {
		// TODO Auto-generated method stub
		return agentData.removeAgent(key);
	}  
    
    
}
